﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using NPOI.SS.UserModel;

namespace MQAMS
{
    public class AttendanceManager
    {
        #region Provate Fields

        private const string _MorTime = "08:30:00";
        private const string _NoonEndTime = "12:30:00";
        private const string _NoonStartTime = "13:30:00";
        private const string _EveTime = "17:30:00";

        private readonly string _file;

        private readonly ScheduleList _schedules;

        private DateTime _dateTime;

        #endregion

        public AttendanceManager(string file, ScheduleList scheduleList)
        {
            _file = file;
            _schedules = scheduleList;
            ConvertXls();
        }

        private void ConvertXls()
        {
            using (var fs = new FileStream(_file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                IWorkbook wb = WorkbookFactory.Create(fs);
                for (int i = 0; i < wb.NumberOfSheets; i++)
                {
                    ISheet sheet = wb.GetSheetAt(i);
                    IEnumerator rows = sheet.GetRowEnumerator();
                    if (rows.MoveNext())
                    {
                        foreach (Schedule schedule in _schedules.Schedules)
                        {
                            bool flag = false;
                            string name = schedule.Name.Replace(" ", "");
                            var atts = new Attendance[schedule.WorkTimes.Count];
                            while (rows.MoveNext())
                            {
                                var row = rows.Current as IRow;
                                if (null != row && string.Equals(name, row.GetCell(1).ToString()))
                                {
                                    Attendance att = ConvertAttendance(row);
                                    atts[att.Date.Day - 1] = att;
                                    flag = true;
                                }
                                else if (flag)
                                {
                                    break;
                                }
                            }
                            var temp = CleanUpAtts(atts, schedule.Name);
                            AuditAc(temp, schedule);
                            rows.Reset();
                        }
                    }
                }
            }
        }

        private Attendance ConvertAttendance(IRow row)
        {
            var attendance = new Attendance
                {
                    Id = short.Parse(row.GetCell(0).ToString()),
                    Name = row.GetCell(1).ToString(),
                    Depart = row.GetCell(2).ToString(),
                    Date = row.GetCell(4).DateCellValue,
                    Weekday = short.Parse(row.GetCell(5).ToString()),
                    Times = short.Parse(row.GetCell(6).ToString()),
                    StartTime = row.GetCell(7).ToString(),
                    SecTime = row.GetCell(8).ToString(),
                    ThiTime = row.GetCell(9).ToString(),
                    Flag = true
                };

            attendance.EndTime = String.CompareOrdinal(attendance.SecTime, attendance.ThiTime) > 0
                                     ? attendance.SecTime
                                     : attendance.ThiTime;
            if (DateTime.MinValue == _dateTime)
            {
                _dateTime = Convert.ToDateTime(attendance.Date.Year + "-" + attendance.Date.Month + "-1");
            }
            return attendance;
        }

        private IList<Attendance> CleanUpAtts(IList<Attendance> attendances, string name)
        {
            Attendance ori = attendances.FirstOrDefault(att => att != null);

            if (null != ori)
            {
                for (int i = 0; i < attendances.Count; i++)
                {
                    if (attendances[i] == null)
                    {
                        attendances[i] = new Attendance
                            {
                                Flag = false,
                                Name = ori.Name,
                                Depart = ori.Depart,
                                Id = ori.Id,
                                Times = 0,
                                StartTime = "今天没打卡",
                                Date = _dateTime.AddDays(i)
                            };
                    }
                }
            }
            else
            {

                attendances = new Attendance[]
                        {
                            new Attendance{
                            Flag = false,
                            Date = _dateTime.AddDays(0),
                            StartTime = @"没有考勤记录",
                            Name = name}
                        };
            }
            return attendances;
        }

        private void AuditAc(IList<Attendance> attendances, Schedule schedule)
        {
            if (attendances.Count == 1)
            {
                XlsHelper.Instance.AddData(attendances.FirstOrDefault());
            }
            else
            {
                for (int index = 0; index < attendances.Count; index++)
                {
                    Attendance attendance = attendances[index];

                    switch (schedule.WorkTimes[index])
                    {
                        case WorkTime.AllDay:
                            if (!attendance.Flag ||
                                string.CompareOrdinal(attendance.StartTime, _MorTime) > 0 ||
                                string.CompareOrdinal(attendance.EndTime, _EveTime) < 0)
                            {
                                XlsHelper.Instance.AddData(attendance);
                            }
                            break;
                        case WorkTime.None:
                            if (attendance.Flag)
                            {
                                XlsHelper.Instance.AddData(attendance);
                            }
                            break;
                        case WorkTime.Am:
                            if (!attendance.Flag ||
                                string.CompareOrdinal(attendance.StartTime, _MorTime) > 0 ||
                                string.CompareOrdinal(attendance.EndTime, _NoonEndTime) < 0)
                            {
                                XlsHelper.Instance.AddData(attendance);
                            }
                            break;
                        case WorkTime.Pm:
                            if (!attendance.Flag ||
                                string.CompareOrdinal(attendance.StartTime, _NoonStartTime) > 0 ||
                                string.CompareOrdinal(attendance.EndTime, _EveTime) < 0)
                            {
                                XlsHelper.Instance.AddData(attendance);
                            }
                            break;
                    }
                }
            }
        }
    }
}